<?php
/**
 * Created by PhpStorm.
 * Author: Shadow
 * Date: 2022/9/15
 * Time: 8:39 上午
 * description: GoodsBusiness.php
 */

namespace app\adminapi\business;


use app\common\model\GoodsImages;
use app\common\model\SpecGoods;
use think\Exception;
use think\facade\Db;

class GoodsBusiness
{

    /**
     * 商品列表
     */
    public static function list(){

        $param  = request()->all();// 接所有的参数
        $limit = request()->get('limit',10);
        if (!is_numeric($limit)) {
            abort(2001,'每页显示的数量只能是数字');
//            throw new Exception("每页显示的数量只能是数字",2001);
        }
        $page = request()->get('page',1);
        if (!is_numeric($page)) {
            abort(2001,'页码只能是数字');
        }

        # 搜索条件
        # 组装条件
        $where = [];
        # 1 商品名称
        if (isset($param['goods_name']) && !empty($param['goods_name'])) {
            $where[] = [
                'goods_name','like',"%{$param['goods_name']}%"
            ];
        }
        # 商品状态 上架/下架
        if (
            isset($param['is_on_sale']) &&  //请求参数中是否传递该参数
            $param['is_on_sale'] != '' &&  // 该参数是否为空
            (in_array($param['is_on_sale'],[0,1]))// 该参数是否在0/1之间
        ){
            $where[] = [
                'is_on_sale','=',$param['is_on_sale']
            ];
        }

        # 区间搜索
        if (
            isset($param['max_price']) && is_numeric($param['max_price']) &&
            isset($param['min_price']) && is_numeric($param['min_price'])
        ) {
            # 当我最大值小于最小值的时候、怎么办？两个值互换
            if ($param['max_price'] < $param['min_price']) {

                list($param['max_price'],$param['min_price']) = [$param['min_price'],$param['max_price']];
            }

            $where[] = [
                'goods_price', '<',$param['max_price']
            ];
            $where[] = [
                'goods_price', '>',$param['min_price']
            ];
        }
        # 列表结果排序
        # 排序字段的集合
        $sort_field_set = [
            'goods_price',
            'sales_num'
        ];
        $sort_style_set= ['desc','asc'];// 排序的方式
        if (
            isset($param['sort_field']) && in_array($param['sort_field'],$sort_field_set) &&
            isset($param['sort_style']) && in_array($param['sort_style'],$sort_style_set)
        ) {
            $sort_field = $param['sort_field'];// 排序的字段
            $sort_style = $param['sort_style'];// 降序/还是升序
        } else {
            # 默认按照价格升序排序
            $sort_field = $sort_field_set[0];
            $sort_style = $sort_style_set[1];// 降序/还是升序
        }

        $data = \app\common\model\Goods::where($where)->with(['cate','brand'])->order($sort_field,$sort_style)->paginate($limit);

        $data = empty($data) ? [] : $data->toArray();
        return $data;
    }


    /**
     * 商品添加
     */
    public static function save($param){
        // 启动事务
        Db::startTrans();
        try {
            # 商品表 goods
            # 商品基本数据
            $goods_data =[
                'goods_name' => $param['goods_name'],
                'goods_price' => $param['goods_price'],
                'market_price' => $param['market_price'],
                'cost_price' => $param['cost_price'],
                'goods_number' => $param['goods_number'],
                'goods_desc' => $param['goods_desc'],
                'goods_logo' => $param['goods_logo'],
                'type_id' => $param['type_id'],
                'brand_id' => $param['brand_id'],
                'goods_attr' => json_encode($param['attr'],JSON_UNESCAPED_UNICODE),//属性信息
            ];
            $goods = \app\common\model\Goods::create($goods_data);
            $goods_id = $goods->id;//获取自增的id
            $spec_goods_data = [];//sku数据
            # 构造数据
            foreach ($param['item'] as $key => $value) {
                $spec_goods_data[] = [
                    'goods_id' => $goods_id,
                    'value_ids' => $value['value_ids'],
                    'value_names' => $value['value_names'],
                    'price' => $value['price'],
                    'cost_price' => $value['cost_price'],
                    'store_count' => $value['store_count'],
                ];
            }
            # 商品规格表 sku表 spec_goods
            invoke(SpecGoods::class)->saveAll($spec_goods_data);
            # 商品相册表
            $images_data = [];
            foreach ($param['goods_images'] as $val) {
                $image = \think\Image::open('./'.$val);
                $big_info = pathinfo($val);// pathinfo()返回文件路径的信息
                // 按照原图的比例生成一个最大为150*150的缩略图并保存为thumb.png
                $thumb_image_path = $big_info['dirname'].'/' . 'thumb_4000_'.$big_info['filename'].'.'.$big_info['extension'];//缩略图的路径
                $image->thumb(400, 400)->save($thumb_image_path);
                $images_data[] = [
                    'goods_id' => $goods_id,
                    'pics_big'=> $val,
                    'pics_sma' => $thumb_image_path
                ];
            }

            invoke(GoodsImages::class)->saveAll($images_data);
            // 提交事务
            Db::commit();
        } catch (\Exception $e) {
            // 回滚事务
            Db::rollback();
            dd($e->getMessage());
            throw new Exception("添加失败");
        }

    }


    /**
     * 商品删除
     * @param $id
     * @throws Exception
     * @throws \think\exception\PDOException
     */
    public static function delete($id){
        // 启动事务
        Db::startTrans();
        try {

            # 删除相册
            $images = GoodsImages::where('goods_id',$id)->select();
            if (!empty($images)) {
                # 销毁文件
                foreach ($images as $path) {
                    unlink($path->pics_big);
                    unlink($path->pics_sma);
                }
                GoodsImages::where('goods_id',$id)->delete();
            }

            # 删除规格值表
            SpecGoods::where('goods_id',$id)->delete();
            # 删除商品spu表
            \app\common\model\Goods::destroy($id);
            // 提交事务
            Db::commit();
        } catch (\Exception $e) {
            // 回滚事务
            Db::rollback();
            throw new Exception("删除失败");
        }
    }

    /**
     * 商品详情
     * @param $id
     * @return array
     * @throws Exception
     */
    public static function detail($id){

        # 也可以查询对应sku信息
        $info = \app\common\model\Goods::with(['brand','cate','type','images'])->find($id);

        $info = $info ? $info->toArray() : [];
        # 查询商品对应的类型以及规格、属性、规格值信息
        $type = \app\common\model\Type::with(['attr','spec','spec.specValue'])
            ->visible([
                'attr'=> [
                    'id','sort','attr_values','attr_name'
                ],
                'spec' =>[
                    'id','sort','spec_name'
                ]
            ])->find($info['type_id']);

        $type = $type ? $type->toArray() : [];

        $info['type'] = $type;

        return $info;

    }


    /**
     * 查询商品编辑所需要的数据
     */
    public static function editor($id){
        /**
         * 商品基本信息
         * 商品相册图片集合（id goods_id pics_big pics_sma）
         * 规格商品集合-SKU
         * 所属品牌信息
         * 所属分类的信息
         */
        $info = \app\common\model\Goods::with(['brand','cate','type','images','sku'])
            ->visible([
                'images' => ['id','goods_id','pics_big','pics_sma'],//指定显示的字段
                'sku' => ['id','goods_id','value_ids','value_names'],
                'type' => ['id','type_name',],
                'brand' => ['id','logo','name'],
                'cate' => ['id','cate_name','pid_path']
            ])->find($id);

        $info = $info ? $info->toArray() : [];
        # 所属模型信息（id type_name attrs specs specs.spec_values）
        $type = \app\common\model\Type::with(['attr','spec','spec.specValue'])
            ->visible([
                'attr'=> [
                    'id','sort','attr_values','attr_name'
                ],
                'spec' =>[
                    'id','sort','spec_name'
                ]
            ])->find($info['type_id']);

        $type = $type ? $type->toArray() : [];

        $info['type'] = $type;

        # 查询所属分类下所有的品牌信息
        $goods_brands = \app\common\model\Brand::field('id,name,logo')->where('cate_id','=',$info['cate_id'])->select();

        # 所有一级分类
        $cate_field = 'id,cate_name,pid,pid_path,pid_path_name';
        $all_one_category = \app\common\model\Category::field($cate_field)->where('pid','=',0)->select();
        $pid_path = explode('_',$info['cate']['pid_path']);
        # 商品所属一级分类下的所有二级分类
        $two_category = \app\common\model\Category::field($cate_field)->where('pid','=',$pid_path[1])->select();
        # 商品所属二级分类下的所有三级分类
        $three_category = \app\common\model\Category::field($cate_field)->where('pid','=',$pid_path[2])->select();
        # 查询所有商品模型信息：（id type_name）
        $all_type = \app\common\model\Type::field('id,type_name')->select();

        $info['goods_brand']      = $goods_brands ? $goods_brands->toArray() : [];
        $info['all_one_category'] = $all_one_category? $all_one_category->toArray() : [];
        $info['two_category']     = $two_category? $two_category->toArray() : [];
        $info['three_category']   = $three_category? $three_category->toArray() : [];
        $info['all_type']         = $all_type? $all_type->toArray() : [];

        return $info;
    }
}